import mongoose, { Schema, Document, Types } from 'mongoose';

export interface IMember extends Document {
  name: string;
  phone: string;
  email?: string;
  avatar?: string;
  gender: 'male' | 'female' | 'other';
  birthDate?: Date;
  height?: number; // cm
  weight?: number; // kg
  emergencyContact?: {
    name: string;
    phone: string;
    relationship: string;
  };
  medicalHistory?: string[];
  fitnessGoals?: string[];
  membershipType: 'monthly' | 'quarterly' | 'yearly' | 'unlimited';
  membershipStartDate: Date;
  membershipEndDate: Date;
  totalSessions: number;
  remainingSessions: number;
  package?: {
    name: string;
    price: number;
    sessions: number;
    validityDays: number;
  };
  trainer?: Types.ObjectId;
  status: 'active' | 'inactive' | 'suspended' | 'expired';
  tags?: string[];
  notes?: string;
  joinDate: Date;
  lastVisitDate?: Date;
  createdAt: Date;
  updatedAt: Date;
}

const MemberSchema: Schema = new Schema({
  name: {
    type: String,
    required: [true, '会员姓名是必填项'],
    trim: true,
    maxlength: [50, '姓名最多50个字符'],
  },
  phone: {
    type: String,
    required: [true, '手机号是必填项'],
    unique: true,
    match: [/^1[3-9]\d{9}$/, '请输入有效的手机号'],
  },
  email: {
    type: String,
    lowercase: true,
    trim: true,
    match: [/^[^\s@]+@[^\s@]+\.[^\s@]+$/, '请输入有效的邮箱地址'],
  },
  avatar: {
    type: String,
    default: null,
  },
  gender: {
    type: String,
    enum: ['male', 'female', 'other'],
    required: [true, '性别是必填项'],
  },
  birthDate: {
    type: Date,
    validate: {
      validator: function(value: Date) {
        return !value || value <= new Date();
      },
      message: '出生日期不能是未来时间'
    }
  },
  height: {
    type: Number,
    min: [50, '身高不能小于50cm'],
    max: [300, '身高不能大于300cm'],
  },
  weight: {
    type: Number,
    min: [20, '体重不能小于20kg'],
    max: [500, '体重不能大于500kg'],
  },
  emergencyContact: {
    name: {
      type: String,
      maxlength: [50, '紧急联系人姓名最多50个字符'],
    },
    phone: {
      type: String,
      match: [/^1[3-9]\d{9}$/, '请输入有效的紧急联系人手机号'],
    },
    relationship: {
      type: String,
      maxlength: [20, '关系最多20个字符'],
    },
  },
  medicalHistory: [{
    type: String,
    maxlength: [100, '病史记录最多100个字符'],
  }],
  fitnessGoals: [{
    type: String,
    maxlength: [50, '健身目标最多50个字符'],
  }],
  membershipType: {
    type: String,
    enum: ['monthly', 'quarterly', 'yearly', 'unlimited'],
    required: [true, '会员类型是必填项'],
  },
  membershipStartDate: {
    type: Date,
    required: [true, '会员开始日期是必填项'],
  },
  membershipEndDate: {
    type: Date,
    required: [true, '会员结束日期是必填项'],
    validate: {
      validator: function(this: IMember, value: Date) {
        return value > this.membershipStartDate;
      },
      message: '会员结束日期必须晚于开始日期'
    }
  },
  totalSessions: {
    type: Number,
    default: 0,
    min: [0, '总课程数不能为负数'],
  },
  remainingSessions: {
    type: Number,
    default: 0,
    min: [0, '剩余课程数不能为负数'],
  },
  package: {
    name: {
      type: String,
      maxlength: [50, '套餐名称最多50个字符'],
    },
    price: {
      type: Number,
      min: [0, '套餐价格不能为负数'],
    },
    sessions: {
      type: Number,
      min: [0, '套餐课程数不能为负数'],
    },
    validityDays: {
      type: Number,
      min: [1, '套餐有效期至少1天'],
    },
  },
  trainer: {
    type: Schema.Types.ObjectId,
    ref: 'User',
  },
  status: {
    type: String,
    enum: ['active', 'inactive', 'suspended', 'expired'],
    default: 'active',
  },
  tags: [{
    type: String,
    maxlength: [20, '标签最多20个字符'],
  }],
  notes: {
    type: String,
    maxlength: [500, '备注最多500个字符'],
  },
  joinDate: {
    type: Date,
    default: Date.now,
  },
  lastVisitDate: {
    type: Date,
  },
}, {
  timestamps: true,
});

// 虚拟字段：年龄
MemberSchema.virtual('age').get(function(this: IMember) {
  if (!this.birthDate) return null;
  const today = new Date();
  const birthDate = new Date(this.birthDate);
  let age = today.getFullYear() - birthDate.getFullYear();
  const monthDiff = today.getMonth() - birthDate.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
    age--;
  }
  return age;
});

// 虚拟字段：BMI
MemberSchema.virtual('bmi').get(function(this: IMember) {
  if (!this.height || !this.weight) return null;
  const heightInMeters = this.height / 100;
  return Math.round((this.weight / (heightInMeters * heightInMeters)) * 10) / 10;
});

// 虚拟字段：剩余天数
MemberSchema.virtual('daysRemaining').get(function(this: IMember) {
  const today = new Date();
  const endDate = new Date(this.membershipEndDate);
  const diffTime = endDate.getTime() - today.getTime();
  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  return Math.max(0, diffDays);
});

// 中间件：更新会员状态
MemberSchema.pre('save', function(this: IMember, next) {
  const today = new Date();
  
  // 检查会员是否过期
  if (this.membershipEndDate < today) {
    this.status = 'expired';
  }
  
  // 检查剩余课程数
  if (this.remainingSessions <= 0 && this.status === 'active') {
    this.status = 'inactive';
  }
  
  next();
});

// 索引
MemberSchema.index({ phone: 1 });
MemberSchema.index({ email: 1 });
MemberSchema.index({ trainer: 1 });
MemberSchema.index({ status: 1 });
MemberSchema.index({ membershipEndDate: 1 });
MemberSchema.index({ joinDate: -1 });
MemberSchema.index({ lastVisitDate: -1 });
MemberSchema.index({ name: 'text', phone: 'text' }); // 文本搜索索引

// 确保虚拟字段在JSON中显示
MemberSchema.set('toJSON', { virtuals: true });
MemberSchema.set('toObject', { virtuals: true });

export default mongoose.model<IMember>('Member', MemberSchema);